package s3

import "github.com/mars/internal/pkg/cat"

// S3Opt 描述S3的行为， 总共64位.
// 64	   : 0 保留位
// [63, 62]: 操作类型: 63 BUCKET	62 OBJECT
// ---读写---
// [61, 60]: 读操作:   61 GET		60 HEAD
// [59, 57]: 写操作:   59 PUT		58 POST		57 DELETE
// -- 分片操作--
// [56 53]:  56 获取uploadId  55  分片上传  54 完成上传  53 终止上传
type S3Opt int64

const (
	baseBit = 1

	BucketOpt = baseBit << 62
	ObjectOpt = baseBit << 61

	readWriteriteShift = 56

	HeadOpt = 0b01000 << readWriteriteShift
	GetOpt  = 0b10000 << readWriteriteShift
	ReadOpt = HeadOpt | GetOpt

	PutOpt     = 0b00100 << readWriteriteShift
	PostOpt    = 0b00010 << readWriteriteShift
	DeleteOpts = 0b00001 << readWriteriteShift
	WriteOpt   = PutOpt | PostOpt | DeleteOpts

	partUploadShift  = 52
	PartOpts         = 0b1111 << partUploadShift
	PartInit         = 0b1000 << partUploadShift
	PartUploadIdOpts = 0b0111 << partUploadShift // 请求中参数中包含UploadId的操作
	PartPut          = 0b0100 << partUploadShift
	PartComplete     = 0b0010 << partUploadShift
	PartAbort        = 0b0001 << partUploadShift
)

func (o S3Opt) IsRead() bool {
	return o&ReadOpt != 0
}

func (o S3Opt) IsHead() bool {
	return o&HeadOpt != 0
}

func (o S3Opt) IsGet() bool {
	return o&GetOpt != 0
}

func (o S3Opt) IsWrite() bool {
	return o&WriteOpt != 0
}

func (o S3Opt) IsPost() bool {
	return o&PostOpt != 0
}

func (o S3Opt) IsPut() bool {
	return o&PutOpt != 0
}

func (o S3Opt) IsDelete() bool {
	return o&DeleteOpts != 0
}

func (o S3Opt) IsBucket() bool {
	return o&BucketOpt != 0
}

func (o S3Opt) IsObject() bool {
	return o&ObjectOpt != 0
}

func (o S3Opt) IsPartOpts() bool {
	return o&PartOpts != 0
}

func (o S3Opt) IsPutPart() bool {
	return o&PartPut != 0
}

// IsPartUploadIdOpts 判断是否是分片上传中非初始化操作
func (o S3Opt) IsPartUploadIdOpts() bool {
	return o&PartUploadIdOpts != 0
}

func (o S3Opt) IsInitPart() bool {
	return o&PartInit != 0
}

func (o S3Opt) IsCompleteUpload() bool {
	return o&PartComplete != 0
}

func (o S3Opt) IsAbort() bool {
	return o&PartAbort != 0
}

// ParseActionDesc 根据 S3Opt 解析出含义描述
// nameType 标识是主节点行为，还是从节点行为
// extra 用户需要添加额外的描述，当前仅仅支持一个可变参数
func (o S3Opt) ParseActionDesc(nameType cat.NameType, extra ...string) (actionType string, actionName string) {
	if o.IsObject() {
		switch {
		case o.IsPutPart():
			actionName = "partUpload"
		case o.IsGet():
			actionName = "download"
		case o.IsHead():
			actionName = "head"
		case o.IsPut():
			actionName = "upload"
		case o.IsDelete():
			actionName = "delete"
		case o.IsInitPart():
			actionName = "partInit"
		case o.IsCompleteUpload():
			actionName = "partComplete"
		default:
			actionName = cat.UnknowType
		}
		if len(extra) == 1 && len(extra[0]) > 0 {
			return cat.CephProxyCatObjectType, string(nameType) + "-" + actionName + "-" + extra[0]
		}
		return cat.CephProxyCatObjectType, string(nameType) + "-" + actionName
	}

	if o.IsBucket() {
		switch {
		case o.IsPut():
			actionName = "create"
		case o.IsDelete():
			actionName = "delete"
		}
		if len(extra) == 1 && len(extra[0]) > 0 {
			return cat.CephProxyCatBucketType, string(nameType) + "-" + actionName + "-" + extra[0]
		}
		return cat.CephProxyCatBucketType, string(nameType) + "-" + actionName
	}

	return cat.UnknowType, cat.UnknowType
}
